/*
 * Copyright 2015-2016 Tumblr, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.tumblr.backboard;

import com.tumblr.backboard.Utils.Property;
import com.tumblr.backboard.Utils.View;
import ohos.agp.components.Component;
import ohos.multimodalinput.event.TouchEvent;

/**
 * Used by Actor and MotionImitator to determine which axis to use when mapping from a TouchEvent.
 *
 * @author ericleong
 * @since 2021-05-07
 */
public enum MotionProperty {
    /**
     * X direction, corresponds to TouchEvent.
     */
    X(View.TRANSLATION_X),
    /**
     * Y direction, corresponds to TouchEvent.
     */
    Y(View.TRANSLATION_Y);

    private static final int VALUE_TWO = 2;

    private Property<Component, Float> mViewProperty;

    MotionProperty(Property<Component, Float> viewProperty) {
        mViewProperty = viewProperty;
    }

    /**
     * get view property
     *
     * @return the view property that this MotionProperty corresponds to
     */

    public Property<Component, Float> getViewProperty() {
        return mViewProperty;
    }

    /**
     * get value
     *
     * @param view the view to inspect
     * @return the current value that this property represents on the given <code>Component</code>.
     */
    public float getValue(Component view) {
        if (view != null) {
            return mViewProperty.get(view);
        }

        return 0;
    }

    /**
     * get value
     *
     * @param event the event to inspect
     * @return the current value that this property represents on the given
     * <code>MotionEvent</code>.
     */
    public float getValue(TouchEvent event) {
        if (event != null) {
            switch (this) {
                case Y:
                    return event.getPointerPosition(0).getY();
                default:
                    return event.getPointerPosition(0).getX();
            }
        }
        return 0;
    }

    /**
     * Note that this method does not check the validity of index.
     *
     * @param event the event to inspect
     * @param index the historical index
     * @return the historical value that this property represents on the given
     * <code>MotionEvent</code>.
     */
    public float getHistoricalValue(TouchEvent event, int index) {
        if (event != null) {
            switch (this) {
                case X:
                    return event.getPointerPosition(index).getX();
                case Y:
                    return event.getPointerPosition(index).getY();
                default:
                    return 0;
            }
        }
        return 0;
    }

    /**
     * Note that this method does not check the validity of index.
     *
     * @param event the event to inspect
     * @return the oldest historical value that this property represents on the given
     * <code>MotionEvent</code>.
     */
    public float getOldestValue(TouchEvent event) {
        return getHistoricalValue(event, 0);
    }

    /**
     * get offset
     *
     * @param view the view to inspect
     * @return the offset from the center that this property represents on the given
     * <code>Component</code>, in pixels.
     */
    public float getOffset(Component view) {
        if (view != null) {
            switch (this) {
                case Y:
                    return (float) -view.getHeight() / VALUE_TWO;
                default:
                    return (float) -view.getWidth() / VALUE_TWO;
            }
        }
        return 0;
    }
}
